using System;
using System.Collections.Generic;
using System.Text;
using VSSDKAssist.Assets.ValueProviders.Base;
using Microsoft.Practices.Common;
using EnvDTE;
using Microsoft.Practices.RecipeFramework.Library;
using System.Collections.Specialized;
using VSSDKAssist.Assets.Helpers;
using System.Globalization;

namespace VSSDKAssist.Assets.ValueProviders.VisualStudio
{
	/// <summary>
	/// Value provider for a project item code class
	/// </summary>
	public class ProjectItemCodeClassValueProvider : ValueProviderBase
	{
		#region Constants
		private const string ProjectArgument = "ProjectArgument";
		private const string TypeName = "TypeName";
		#endregion

		#region Fields
		private string projectArgument;
		private string typeName;
		#endregion

		/// <summary>
		/// Contains code that will be called before actions are executed.
		/// </summary>
		/// <param name="currentValue">An <see cref="T:System.Object"/> that contains the current value of the argument.</param>
		/// <param name="newValue">When this method returns, contains an <see cref="T:System.Object"/> that contains
		/// the new value of the argument, if the returned value
		/// of the method is <see langword="true"/>. Otherwise, it is ignored.</param>
		/// <returns>
		/// 	<see langword="true"/> if the argument value should be replaced with
		/// the value in <paramref name="newValue"/>; otherwise, <see langword="false"/>.
		/// </returns>
		/// <remarks>By default, always returns <see langword="false"/>, unless overridden by a derived class.</remarks>
		public override bool OnBeforeActions(object currentValue, out object newValue)
		{
			newValue = null;

			if((currentValue == null) && (this.ExecutionStage != Stage.OnBeginRecipe))
			{
				Project project = DictionaryService.GetValue(projectArgument) as Project;

				if(project != null)
				{
					typeName =
						string.Format(
							CultureInfo.CurrentCulture,
							"{0}.{1}",
							project.Properties.Item("DefaultNamespace").Value.ToString(),
							typeName);

					CodeClass packageClass =
						FileCodeModelHelper.FindCodeElementByTypeName(
						project, typeName, vsCMElement.vsCMElementClass) as CodeClass;

					newValue = packageClass;
					return true;
				}
			}

			return false;
		}

		/// <summary>
		/// Called when [configure].
		/// </summary>
		/// <param name="attributes">The attributes.</param>
		protected override void OnConfigure(StringDictionary attributes)
		{
			if(attributes == null)
				throw new ArgumentNullException("attributes");

			if(attributes.ContainsKey(ProjectArgument))
			{
				projectArgument = attributes[ProjectArgument];
			}

			if(attributes.ContainsKey(TypeName))
			{
				typeName = attributes[TypeName];
			}
		}
	}
}